package boerse.main.Asset;

import boerse.main.Exceptions.NegativeShareCountException;
import boerse.main.Exceptions.NegativeValueException;
import boerse.main.Exceptions.NotEnoughMoneyException;
import boerse.main.Logger.GameLogger;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A collection from shares Items
 * @author Domi
 *
 */
public class ShareDeposit extends Assets{

    private Hashtable<String,ShareItem> shareDeposit;
    private Hashtable<String, Long> buyPrice;
//    private Logger gameLogger;

	
	public ShareDeposit(String name)  {
		super(name);
//        try {
//			gameLogger = GameLogger.getLogger("ShareDepositCfg.txt", rb, locale);
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
        shareDeposit = new Hashtable<String, ShareItem>();
        buyPrice = new Hashtable<String, Long>();
	}
	
	/**
	 * Buy more shares. If allready shares from the same type was bought the new shares wil be added(quantity raised)
	 * @param share
	 * @param quantity
	 * @param cashAccount
	 * @throws NotEnoughMoneyException
	 * @throws NegativeValueException
	 */
	public void buy(Share share, long quantity, CashAccount cashAccount) throws NotEnoughMoneyException, NegativeValueException
	{
        if(shareDeposit.containsKey(share.getName())) {
            cashAccount.removeMoney(quantity*share.getPrice());
            setBuyPrice(share, quantity);
            shareDeposit.get(share.getName()).addShare(quantity);
        } else {
            ShareItem newShareItem = new ShareItem(quantity, share);
            cashAccount.removeMoney(quantity*share.getPrice());
            shareDeposit.put(share.getName(),newShareItem);
            buyPrice.put(share.getName(), share.getPrice());
        }
//        gameLogger.getResourceBundle();
//        gameLogger.log(Level.FINEST, "<ShareDeposit> Player " + name + " is buying " + quantity + " " + share.getName() + " shares at the current rate of " + share.getPrice() + " Euro.");
	}


/**
 * Buy more shares. If allready shares from the same type was bought the new shares will be deleted(quantity raised)
 * At 0 shares the ShareItem will be deleted from list
 * @param share
 * @param quantity
 * @param cashAccount
 * @throws NegativeValueException
 * @throws NegativeShareCountException
 */
    public void sell(Share share, long quantity, CashAccount cashAccount) throws NegativeValueException, NegativeShareCountException
	{
        if (quantity < 1) {
//            gameLogger.log(Level.WARNING, " <ShareDeposit> Player " + name + " is trying to buy shares using sell!");
            throw new NegativeValueException();
        }
        else if (shareDeposit.get(share.getName()).getQuantity() == quantity) {
            shareDeposit.remove(share.getName());
            buyPrice.remove(share.getName());
//            gameLogger.log(Level.FINEST, "<ShareDeposit> Player " + name + " is selling " + quantity + " " + share.getName() + " shares at the current rate of " + share.getPrice() + " Euro.");
        }
        else {
            shareDeposit.get(share.getName()).removeShare(quantity);
//            gameLogger.log(Level.FINEST, "<ShareDeposit> Player " + name + " is selling " + quantity + " " + share.getName() + " shares at the current rate of " + share.getPrice() + " Euro.");
        }
	}
	
		
	public long determinePrice() {

        Object [] shareDepositarr = shareDeposit.keySet().toArray();
		long price = 0;
		for(int i = 0; i < shareDepositarr.length; ++i) {
            price += shareDeposit.get(shareDepositarr[i]).determinePrice();
        }
		return price;
	}
	
	
	public String toString() {

		String s = "";
        Object [] shareDepositarr = shareDeposit.keySet().toArray();
        Object [] buyPricearr = buyPrice.keySet().toArray();
		for (int i = 0; i < shareDepositarr.length; i++)
			s = s + shareDeposit.get(shareDepositarr[i]) + ":" + buyPrice.get(buyPricearr[i]) + "\n";
		
		return s;
	}

	/**
	 * Get the Buy price from the shares. The Buy price is a average figure from all Shares in Share Item
	 * @param share
	 * @return
	 */
    public long getBuyPrice(Share share) {

        Object [] shareDepositarr = shareDeposit.keySet().toArray();
        for(int i = 0; i < shareDepositarr.length; ++i) {
            if (shareDeposit.get(shareDepositarr[i]).getName().equals(share.getName())) {
                return buyPrice.get(shareDepositarr[i]);
            }
        }
        return 0;
    }

    public long getQuantity(Share share) {

        Object [] shareDepositarr = shareDeposit.keySet().toArray();
        for(int i = 0; i < shareDepositarr.length; ++i) {
            if (shareDeposit.get(shareDepositarr[i]).getName().equals(share.getName())) {
                return shareDeposit.get(shareDepositarr[i]).getQuantity();
            }
        }
        return 0;
    }
	
	public ShareItem[] getAllSharesAsSnapshot() {

        Object [] shareDepositarr = shareDeposit.keySet().toArray();
        ShareItem[] shareCopy = new ShareItem[shareDepositarr.length];

		
		for (int i = 0; i < shareCopy.length; i++) {
			shareCopy[i] = shareDeposit.get(shareDepositarr[i]);
		}
		
		return shareCopy;
        /* return Map
        Object [] shareDepositarr = shareDeposit.keySet().toArray();
        Map <String, ShareItem> shareDepositCopy;

        for (int i = 0; i < shareDepositarr.length; i++) {
            shareDeposit.put(shareDeposit.get(shareDepositarr[i]).getName(), shareDeposit.get(shareDepositarr[i]));
        }

        return shareDepositCopy;
         */
	}

    private void setBuyPrice(Share share, Long quantity) {
        long oldQuantity = shareDeposit.get(share.getName()).getQuantity();
        long aBP = (oldQuantity * buyPrice.get(share.getName()) + quantity * share.getPrice()) / (oldQuantity + quantity);
        buyPrice.remove(share.getName());
        buyPrice.put(share.getName(),aBP);
    }
}

